'use strict';

Object.defineProperty(exports, "__esModule", {
	value: true
});
const func = {};
exports.default = func;
/**
 * <@enum=list key="key" value="value"></>
 */

func['enum'] = { type: 'enum', async func(node, scope, next) {
		await this.repeat(node.list, scope, node.value, { value: node.param.value, key: node.param.key });
	} };

/**
 * <@if=``script``>
 * <|elseif=``script``>
 * <|else>
 * </>
 */
func['if'] = { type: 'if', async func(node, scope, next) {
		let thisnode = node;
		let childScope = this.scope(scope);
		for (let i = 0, l = node.sub.length, list = node.sub; i <= l; i++) {
			if (await thisnode.value.exec(childScope)) {
				return await this.parseList(thisnode.list, childScope);
			}
			if (i >= l) {
				break;
			}
			thisnode = list[i];
			if (thisnode.name === 'else') {
				return await this.parseList(thisnode.list, childScope);
			} else if (thisnode.name !== 'elseif') {
				break;
			}
		}
	} };

/**
 * <@while=``script``></>
 */
func['while'] = { type: 'while', async func({ value, list }, scope, next) {
		const symbol = this.symbol;
		const Scope = this.scope;
		while (await value.exec(scope)) {
			try {
				await this.parseList(list, Scope(scope));
			} catch (sign) {
				if (sign === symbol.BREAK) {
					return;
				} else if (typeof sign === "object" && sign.type === symbol.BREAK) {
					if (!sign.number || sign.number <= 0) {
						return;
					}
					sign.number--;
					if (sign.number <= 0) {
						throw symbol.BREAK;
					}
					return;
				} else if (sign && sign.type === symbol.CONTINUE) {
					if (sign.number > 0) {
						sign.number--;
						if (sign.number <= 0) {
							throw symbol.CONTINUE;
						}
						throw sign;
					}
				} else if (sign !== symbol.CONTINUE) {
					throw sign;
				}
			}
		}
	} };

/**
 * <@break/>
 */
func['break'] = { type: 'break', async func(node, scope, next) {
		throw this.symbol.BREAK;
	} };

/**
 * <@continue/>
 */
func['continue'] = { type: 'continue', async func(node, scope, next) {
		throw this.symbol.CONTINUE;
	} };